package com.deyuanyun.pic.settings.task.util;

import com.deyuanyun.pic.settings.task.quartz.CalendarIntervalTriggerImpl;
import org.joda.time.DateTime;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.spi.OperableTrigger;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 *  获取任务日历工具类
 *  @author axiao(xj08.dream@gmail.com)
 *  @date 2016-09-10
 *  @version 1.0
 *  Histroy: [修改人][时间][描述]
 */
public class TaskCalendarUtil {


    /**
     * 指定触发器及时间年月，返回该时间指定年月从第一天到最后一天的任务的所有执行时间
     * @param trigger 触发器
     * @param date 时间只要年月，指定范围默认是指定年月从第一天凌晨零点整到最后一天的23:59:59的范围
     * @return
     * @throws Exception 找不到任务会有异常抛出
     * @author axiao(xj08.dream@gmail.com)
     * @date 2016-09-10
     */
    public static List<Date> taskTimesBetween(Trigger trigger, Date date) {
        DateTime from = null, to = null;
        DateTime dateTime = new DateTime(date);
        DateTime.Property property =  dateTime.dayOfMonth();
        from = dateTime.withDayOfMonth(property.getMinimumValue()).withTime( 0, 0, 0, 0);
        to = dateTime.withDayOfMonth(property.getMaximumValue()).withTime(23, 59, 59, 0);
        return taskTimesBetween(trigger, from.toDate(), to.toDate());
    }


    /**
     * 指定任务名、组名，以及时间年月，返回该时间指定年月从第一天到最后一天的任务的所有执行时间
     * @param name 任务名
     * @param group 组名
     * @param date 时间只要年月，指定范围默认是指定年月从第一天凌晨零点整到最后一天的23:59:59的范围
     * @return
     * @throws Exception 找不到任务会有异常抛出
     * @author axiao(xj08.dream@gmail.com)
     * @date 2016-09-10
     */
    public static List<Date> taskTimesBetween(String name,String group, Date date) {
        DateTime from = null, to = null;
        DateTime dateTime = new DateTime(date);
        DateTime.Property property =  dateTime.dayOfMonth();
        from = dateTime.withDayOfMonth(property.getMinimumValue()).withTime( 0, 0, 0, 0);
        to = dateTime.withDayOfMonth(property.getMaximumValue()).withTime(23, 59, 59, 0);
        return taskTimesBetween(QuartzManagerUtil.getTrigger(name, group), from.toDate(), to.toDate());
    }

    /**
     * 指定触发器及时间范围，返回该时间范围任务的所有执行时间
     * @param trigger 触发器
     * @param from 开始时间，包含时分秒
     * @param to 结束时间，包含时分秒
     * @return
     * @throws Exception 找不到任务会有异常抛出
     * @author axiao(xj08.dream@gmail.com)
     * @date 2016-09-10
     */
    public static List<Date> taskTimesBetween(Trigger trigger, Date from, Date to) {
        if(trigger != null && trigger instanceof CalendarIntervalTriggerImpl) {
            return  computeFireTimesBetween((OperableTrigger)trigger, null,from ,to);
        }
        return null;
    }

    public static List<Date> computeFireTimesBetween(OperableTrigger trigg,
                                                     org.quartz.Calendar cal, Date from, Date to) {
        LinkedList<Date> lst = new LinkedList<Date>();

        OperableTrigger t = (OperableTrigger) trigg.clone();

        if (t.getNextFireTime() == null) {
            t.setStartTime(from);
            t.setEndTime(to);
            t.computeFirstFireTime(cal);
        }
        t.computeFirstFireTime(cal);//重新根据开始时间计算nextFireTime时间
        while (true) {
            Date d = t.getNextFireTime();
            if (d != null) {
                if (d.before(from)) {
                    t.triggered(cal);
                    continue;
                }
                if (d.after(to)) {
                    break;
                }
                lst.add(d);
                t.triggered(cal);
            } else {
                break;
            }
        }

        return java.util.Collections.unmodifiableList(lst);
    }
}
